﻿var CTX = {
    initialize: function () {
        jQuery(CTX.Util.is.types).each(function (index, c) {
            CTX.Util.is[c] = (function (type) {
                return function (obj) {
                    return Object.prototype.toString.call(obj) == "[object " + type + "]";
                };
            })(c);
        });
    }
};
CTX.Constants = {
    WIDGET_INFO: "widgetinfo"
};
CTX.Util = {
    is: { types: ["Array", "RegExp", "Date", "Number", "String", "Object", "HTMLDocument"] } 
};

CTX.Widgets = {
    attributes: {
        TEMPLATECONTAINER_ID: "containerid",
        TEMPLATE_ID: "templateid",
        COLUMN_ID: "columnid",
        WIDGET_ID: "widgetid",
        WIDGET_TYPE_ID: "widgettypeid"
    },
    options: null,
    allWidgetInfos: [],
    initialize: function (columnClass, widgetClass, newWidgetClass, newWidgetTitleClass, handleClass, lockWidgetClass, placeholderClass, columnPostBackTrigger) {
        this.allWidgetInfos = [];
        this.options = {
            columnClass: columnClass,
            widgetClass: widgetClass,
            newWidgetClass: newWidgetClass,
            newWidgetTitleClass: newWidgetTitleClass,
            handleClass: handleClass,
            lockWidgetClass: lockWidgetClass,
            placeholderClass: placeholderClass,
            columnPostbackTrigger: columnPostBackTrigger
        };

        $("." + columnClass).each(function () {
            var column = $(this);
            column.find("." + widgetClass).each(function (index, widgetContainer) {
                var widgetInfo = CTX.Widgets.WidgetInfo.getInstance(
                                $(widgetContainer).attr(CTX.Widgets.attributes.WIDGET_ID),
                                $(widgetContainer).attr(CTX.Widgets.attributes.WIDGET_TYPE_ID),
                                column.attr(CTX.Widgets.attributes.COLUMN_ID),
                                column.attr(CTX.Widgets.attributes.TEMPLATECONTAINER_ID),
                                index,
                                column.attr(CTX.Widgets.attributes.TEMPLATE_ID)
                         );
                CTX.Widgets.allWidgetInfos.push(widgetInfo);
                $(widgetContainer).data(CTX.Constants.WIDGET_INFO, widgetInfo);
            });
        });

        $("." + newWidgetClass).each(function () {
            var widgetInfo = CTX.Widgets.WidgetInfo.getInstance(
                                    null,
                                    $(this).attr(CTX.Widgets.attributes.WIDGET_TYPE_ID),
                                    null,
                                    null,
                                    -1,
                                    -1);
            $(this).data(CTX.Constants.WIDGET_INFO, widgetInfo);
            $(this).data("width", $(this).width());
        });

        this.initDragDrop(columnClass, widgetClass, newWidgetClass, newWidgetTitleClass, handleClass, lockWidgetClass, placeholderClass, columnPostBackTrigger);
    },
    initializeWithOptions: function (_options) {
        this.initialize(_options.columnClass, _options.widgetClass, _options.newWidgetClass,
                                 _options.newWidgetTitleClass, _options.handleClass, _options.lockWidgetClass,
                                 _options.placeholderClass, _options.columnPostBackTrigger);
    },
    reinitialize: function () {
        this.initializeWithOptions(this.options);
    },
    initDragDrop: function (columnClass, widgetClass, newWidgetClass, newWidgetTitleClass, handleClass, lockWidgetClass, placeholderClass, columnPostBackTrigger) {

        var allColumns = jQuery("." + columnClass);
        //Destroy the old sortable data
        allColumns.each(function () {
            var plugin = jQuery(this).data("sortable");
            if (plugin) {
                plugin.destroy();
            }
        });

        var itemsSelector = (lockWidgetClass == null)
                                    ? ("." + widgetClass)
                                    : ("." + widgetClass + ":not(." + lockWidgetClass + ")");
        // Init the column's sortable
        allColumns.sortable({
            connectWith: "." + columnClass,
            cursor: "move",
            cancel: 'a, input',
            handle: "." + handleClass,
            placeholder: placeholderClass,
            items: itemsSelector,
            tolerance: "pointer",
            revert: 1000,
            start: function (event, ui) {
                ui.placeholder.height(ui.item.height());
            },
            change: function (event, ui) {
                var w = ui.item.width();
                ui.placeholder.width(w);
                ui.helper.css("width", w);

                if (ui.item != undefined) {
                    ui.placeholder.height(ui.item.height());
                }
                else {
                    ui.placeholder.height(200);
                }
            },
            stop: function (event, ui) {
                var column = $(ui.item).parents("." + columnClass);
                var columnId = column.attr(CTX.Widgets.attributes.COLUMN_ID);
                var index = column.find("." + widgetClass).index(ui.item);
                var templateId = column.attr(CTX.Widgets.attributes.TEMPLATE_ID);

                // Drag a new widget
                if (ui.item.hasClass(newWidgetClass)) {
                    var newWidgetTitle = newWidgetTitleClass != "" ? ui.item.find("." + newWidgetTitleClass).text() : ui.item.text();
                    var newWidgetSnap = CTX.Widgets.createNewWidgetSnap(newWidgetTitle);
                    ui.item.replaceWith(newWidgetSnap);
                    var widgetInfo = CTX.Widgets.WidgetInfo.getInstance(
                                    null,
                                    $(ui.item).attr(CTX.Widgets.attributes.WIDGET_TYPE_ID),
                                    columnId,
                                    null,
                                    column.find("." + widgetClass).index(newWidgetSnap),  //Need get index at this point!!
                                    templateId);

                    allColumns.sortable("disable");
                    CTX.Widgets.Actions.onAddWidget(widgetInfo,
                            function (data) {
                                CTX.Widgets.Refresh();
                            },
                            function (data) {
                                CTX.Widgets.Refresh();
                            });
                }
                // Move widget from others
                else {
                    var _fromWidgetInfo = $(ui.item).data(CTX.Constants.WIDGET_INFO);
                    if (columnId != _fromWidgetInfo.ColumnID || index != _fromWidgetInfo.Index) {
                        var _toWidgetInfo = CTX.Widgets.WidgetInfo.copyFrom(_fromWidgetInfo);
                        _toWidgetInfo.ColumnID = columnId;
                        _toWidgetInfo.Index = index;

                        allColumns.sortable("disable");
                        CTX.Widgets.Actions.onMoveWidget(_fromWidgetInfo, _toWidgetInfo,
                                                        function (data) {
                                                            CTX.Widgets.Refresh();
                                                        },
                                                        function (data) {
                                                            CTX.Widgets.Refresh();
                                                        });
                    }
                }
            }
        });

        //Init drag new widget to column
        $("." + newWidgetClass).draggable({
            connectToSortable: "." + columnClass,
            helper: "clone",
            tolerance: "pointer"
        });

    },
    createNewWidgetSnap: function (widgetTitle) {
        return $('<div class="widgetContainer">'
                        + '<div class="widgetHeader">'
                        + '<span class="widgetTitle">&nbsp;</span>'
                        + '<div class="widgetHeaderButton">'
                        + '<a id="collapseWidgetAnchor" class="editwidget widget_collapse"></a>'
                        + '</div>'
                        + '</div>'
                        + '<div class="widgetHolder">'
                        + 'loading ...'
                        + '</div>'
                        + '<div class="widgetFooter">'
                        + '</div>'
                        + '</div>').find(".widgetTitle").html(widgetTitle).parents(".widgetContainer");
    },
    Refresh: function () {
        eval($(CTX.Widgets.options.columnPostbackTrigger).attr("href"));
    },
    Actions: {
        onAddWidget: function (_widgetInfo, successCallback, failedCallback) {
            CTX.ServiceProxy.Widgets.AddWidgets(_widgetInfo.WidgetTypeId, _widgetInfo.Index, _widgetInfo.ColumnID, _widgetInfo.TemplateId, successCallback, failedCallback);
            return this;
        },
        onMoveWidget: function (_fromWidgetInfo, _toWidgetInfo, successCallback, failedCallback) {
            CTX.ServiceProxy.Widgets.MoveWidgets(_fromWidgetInfo.ID, _fromWidgetInfo.ColumnID, _fromWidgetInfo.Index,
                                                   _toWidgetInfo.ColumnID, _toWidgetInfo.Index,
                                                   successCallback,
                                                   failedCallback);
            return this;
        },
        onRemoveWidget: function (id, successCallback, failedCallback) {
            CTX.ServiceProxy.Widgets.RemoveWidget(id, successCallback, failedCallback);
            return this;
        }
    }
};

CTX.Widgets.WidgetInfo = function (_id, _typeid, _columnid, _containerId, _index,_templateId) {
    this.ID = new Number(_id);
    this.ColumnID = _columnid;
    this.ContainerID = new Number(_containerId);
    this.Index = new Number(_index);
    this.WidgetTypeId = new Number(_typeid);
    this.TemplateId = new Number(_templateId);
}

CTX.Widgets.WidgetInfo.getInstance = function (_id, _typeid, _columnid, _containerId, _index, _templateId) {
    return new CTX.Widgets.WidgetInfo(_id, _typeid, _columnid, _containerId, _index, _templateId);
};

CTX.Widgets.WidgetInfo.copyFrom = function (_fromWidgetInfo) {
    if (_fromWidgetInfo) {
        return new CTX.Widgets.WidgetInfo(_fromWidgetInfo.ID,
                                               _fromWidgetInfo.WidgetTypeId,
                                               _fromWidgetInfo.ColumnID,
                                               _fromWidgetInfo.ContainerID,
                                               _fromWidgetInfo.Index,
                                               _fromWidgetInfo.TemplateId);
    }
    return null;
};

CTX.ServiceProxy = {
    Widgets: {
        getServiceInstance: function () {
            return new CMT.Services.WidgetsService();
        },
        AddWidgets: function (type, index, columnId, templateId, successCallBack, failedCallBack) {
            var serviceInstance = this.getServiceInstance();
            serviceInstance.AddWidget(type, index, columnId, templateId, function (result) {
                if (result == true) {
                    if (successCallBack != null) {
                        successCallBack(result);
                    }
                }
                else {
                    if (failedCallBack != null) {
                        failedCallBack({ code: 0, data: result });
                    }
                }
            }, function (result) {
                if (failedCallBack != null) {
                    failedCallBack({ code: 1, data: result });
                }
            });
        },
        MoveWidgets: function (id, fromColumnId, fromIndex, toColumnId, toIndex, successCallBack, failedCallBack) {
            var serviceInstance = this.getServiceInstance();
            serviceInstance.MoveWidget(id, fromColumnId, fromIndex, toColumnId, toIndex, function (result) {
                if (result == true) {
                    if (successCallBack != null) {
                        successCallBack(result); 
                    }
                }
                else {
                    if (failedCallBack != null) {
                        failedCallBack({ code: 0, data: result });
                    }
                }
            }, function (result) {
                if (failedCallBack != null) {
                    failedCallBack({ code: 1, data: result });
                }
            });
        },
        RemoveWidget: function (id, successCallBack, failedCallBack) {
            var serviceInstance = this.getServiceInstance();
            serviceInstance.RemoveWidget(id, function (result) {
                if (result == true) {
                    if (successCallBack != null) {
                        successCallBack(result);
                    }
                }
                else {
                    if (failedCallBack != null) {
                        failedCallBack({ code: 0, data: result });
                    }
                }
            }, function (result) {
                if (failedCallBack != null) {
                    failedCallBack({ code: 1, data: result });
                }
            });
        },
        TestService: function (id, successCallBack, failedCallBack) {
            var serviceInstance = this.getServiceInstance();
            serviceInstance.TestService(id, function (result) {
                if (result == true) {
                    if (successCallBack != null) {
                        successCallBack(result);
                    }
                }
                else {
                    if (failedCallBack != null) {
                        failedCallBack({ code: 0, data: result });
                    }
                }
            }, function (result) {
                if (failedCallBack != null) {
                    failedCallBack({ code: 1, data: result });
                }
            });
        }
    }
};

CTX.initialize();


